#import "SSMemoryInfo.h"
#import <sys/stat.h>
#import <mach/mach.h>
@implementation SSMemoryInfo
+ (double)totalMemory {
	@try {
        double totalMemory = 0.00;
        double allMemory = [[NSProcessInfo processInfo] physicalMemory];
	    totalMemory = (allMemory / 1024.0) / 1024.0;
        int toNearest = 256;
        int remainder = (int)totalMemory % toNearest;
        if (remainder >= toNearest / 2) {
            totalMemory = ((int)totalMemory - remainder) + 256;
        } else {
            totalMemory = (int)totalMemory - remainder;
        }
        if (totalMemory <= 0) {
            return -1;
        }
        return totalMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
+ (double)freeMemory:(BOOL)inPercent {
	@try {
        double totalMemory = 0.00;
		vm_statistics_data_t vmStats;
		mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
		kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
		if(kernReturn != KERN_SUCCESS) {
			return -1;
		}
        if (inPercent) {
            double fm = [self totalMemory];
            double am = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
            totalMemory = (am * 100) / fm;
        } else {
            totalMemory = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
        }
        if (totalMemory <= 0) {
            return -1;
        }
        return totalMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
+ (double)usedMemory:(BOOL)inPercent {
	@try {
        double totalUsedMemory = 0.00;
		mach_port_t host_port;
		mach_msg_type_number_t host_size;
		vm_size_t pagesize;
		host_port = mach_host_self();
		host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
		host_page_size(host_port, &pagesize);
		vm_statistics_data_t vm_stat;
		if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            return -1;
		}
		natural_t usedMemory = (natural_t)((vm_stat.active_count +
                                vm_stat.inactive_count +
                                vm_stat.wire_count) * pagesize);
		natural_t allMemory = [self totalMemory];
        if (inPercent) {
            double um = (usedMemory /1024) / 1024;
            double am = allMemory;
            totalUsedMemory = (um * 100) / am;
        } else {
            totalUsedMemory = (usedMemory / 1024.0) / 1024.0;
        }
        if (totalUsedMemory <= 0) {
            return -1;
        }
        return totalUsedMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
+ (double)activeMemory:(BOOL)inPercent {
	@try {
        double totalMemory = 0.00;
		mach_port_t host_port;
		mach_msg_type_number_t host_size;
		vm_size_t pagesize;
		host_port = mach_host_self();
		host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
		host_page_size(host_port, &pagesize);
		vm_statistics_data_t vm_stat;
		if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            return -1;
		}
        if (inPercent) {
            double FM = [self totalMemory];
            double AM = ((vm_stat.active_count * pagesize) / 1024.0) / 1024.0;
            totalMemory = (AM * 100) / FM;
        } else {
            totalMemory = ((vm_stat.active_count * pagesize) / 1024.0) / 1024.0;
        }
        if (totalMemory <= 0) {
            return -1;
        }
        return totalMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
+ (double)inactiveMemory:(BOOL)inPercent {
	@try {
        double totalMemory = 0.00;
		mach_port_t host_port;
		mach_msg_type_number_t host_size;
		vm_size_t pagesize;
		host_port = mach_host_self();
		host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
		host_page_size(host_port, &pagesize);
		vm_statistics_data_t vm_stat;
		if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            return -1;
		}
        if (inPercent) {
            double FM = [self totalMemory];
            double AM = ((vm_stat.inactive_count * pagesize) / 1024.0) / 1024.0;
            totalMemory = (AM * 100) / FM;
        } else {
            totalMemory = ((vm_stat.inactive_count * pagesize) / 1024.0) / 1024.0;
        }
        if (totalMemory <= 0) {
            return -1;
        }
        return totalMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
+ (double)wiredMemory:(BOOL)inPercent {
	@try {
        double totalMemory = 0.00;
		mach_port_t host_port;
		mach_msg_type_number_t host_size;
		vm_size_t pagesize;
		host_port = mach_host_self();
		host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
		host_page_size(host_port, &pagesize);
		vm_statistics_data_t vm_stat;
		if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            return -1;
		}
        if (inPercent) {
            double FM = [self totalMemory];
            double AM = ((vm_stat.wire_count * pagesize) / 1024.0) / 1024.0;
            totalMemory = (AM * 100) / FM;
        } else {
            totalMemory = ((vm_stat.wire_count * pagesize) / 1024.0) / 1024.0;
        }
        if (totalMemory <= 0) {
            return -1;
        }
        return totalMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
+ (double)purgableMemory:(BOOL)inPercent {
	@try {
        double totalMemory = 0.00;
		mach_port_t host_port;
		mach_msg_type_number_t host_size;
		vm_size_t pagesize;
		host_port = mach_host_self();
		host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
		host_page_size(host_port, &pagesize);
		vm_statistics_data_t vm_stat;
		if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
            return -1;
		}
        if (inPercent) {
            double fm = [self totalMemory];
            double am = ((vm_stat.purgeable_count * pagesize) / 1024.0) / 1024.0;
            totalMemory = (am * 100) / fm;
        } else {
            totalMemory = ((vm_stat.purgeable_count * pagesize) / 1024.0) / 1024.0;
        }
        if (totalMemory <= 0) {
            return -1;
        }
        return totalMemory;
	}
	@catch (NSException *exception) {
        return -1;
	}
}
@end
